﻿//_______________________________________________________________________________________________________________________
// Copy Right (c) 2010, 2011 SapiensIT Consulting GmbH, all rights reserved
//_______________________________________________________________________________________________________________________
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//_______________________________________________________________________________________________________________________
// PROJECT:     sapiens.at.SharePoint.LookupPicker (SharePoint 2010/V4)
//_______________________________________________________________________________________________________________________
// VERSION:     2.0
//_______________________________________________________________________________________________________________________
// DESCRIPTION: 
//_______________________________________________________________________________________________________________________
// LICENSE:     Different licens Types apply to different file types:
//               - Source code files are governed by the MICROSOFT PUBLIC LICENSE (Ms-PL)
//               - Binary files are governed by MSDN CODE GALLERY BINARY LICENSE
//               - Documentation files are governed by CREATIVE COMMONS ATTRIBUTION 3.0 LICENSE
//
//               The licenses can be found at the projects source location.
//               If you do not agree, don't use it!
// 
//_______________________________________________________________________________________________________________________
// Start SharePoint Branding, visit http://www.cliggin.com! Visit us on http://www.sapiens.at! Tell your friends! 
//_______________________________________________________________________________________________________________________
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint.WebControls;
using System.Data;
using Microsoft.SharePoint;
using System.Web.UI.WebControls;
using System.Collections;
using Sapiens.at.SharePoint.Utils;
using QB = Sapiens.at.SharePoint.Utils.QueryBuilder;
using Res = Sapiens.at.SharePoint.Fields.Resources.Sapiens_at_SharePoint_LookupPicker;

namespace Sapiens.at.SharePoint.Fields
{
    /// <summary>
    /// Control that executes the query for the <see cref="LookupPicker"/>.
    /// </summary>
    public class LookupPickerQueryControl : SimpleQueryControl
    {
        const string IDColumnName = "__ID";
        const string TitleColumnName = "__TITLE";
        //const string LookupField = "__MAINDISPLAY";

        LookupPickerDialog LookupPickerDialog
        {
            get { return (LookupPickerDialog)PickerDialog; }
        }

        /// <summary>
        /// Transforms a datarow to a PickerEntity.
        /// </summary>
        /// <param name="entityDataRow"></param>
        /// <returns></returns>
        public override PickerEntity GetEntity(DataRow entityDataRow)
        {
            if (entityDataRow == null)
            {
                throw new ArgumentNullException("entityDataRow");
            }
            var displayText = entityDataRow.Table.Columns.Contains(LookupPickerDialog.LookupPicker.PickerData.LookupField) ?
                entityDataRow[LookupPickerDialog.LookupPicker.PickerData.LookupField].ToString() : TitleColumnName;
            PickerEntity entity = new PickerEntity();
            entity.Key = (string)entityDataRow[IDColumnName];
            entity.IsResolved = true;
            entity.DisplayText = displayText;
            entity.Description = displayText;
            SPList list = LookupPickerDialog.List;
            foreach (string viewFieldName in LookupPickerDialog.LookupPicker.PickerData.AllDisplayFields)
            {
                SPField viewField = list.Fields.GetField(viewFieldName);
                entity.EntityData[viewField.InternalName] = entityDataRow[viewField.InternalName];
            }
            if (!entity.EntityData.ContainsKey(LookupPickerDialog.LookupPicker.PickerData.IDFieldName))
            {
                entity.EntityData.Add(LookupPickerDialog.LookupPicker.PickerData.IDFieldName, entityDataRow[IDColumnName]);
            }
            return entity;
        }

        /// <summary>
        /// Populates the filter dropdown.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            EnsureChildControls();
            SPList list = LookupPickerDialog.List;

            // Populate filter column list
            foreach (string searchField in LookupPickerDialog.LookupPicker.PickerData.AllSearchFields)
            {
                SPField field = list.Fields.GetField(searchField);
                ColumnList.Items.Add(new ListItem(field.Title, field.InternalName));
            }
            base.OnLoad(e);
        }

        /// <summary>
        /// Creates and executes the query.
        /// </summary>
        /// <param name="search"></param>
        /// <param name="groupName"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        protected override int IssueQuery(string search, string groupName, int pageIndex, int pageSize)
        {
            DataTable resultsTable = new DataTable();

            //
            // 1. Create the result table columns
            //

            // Always store a column with the item ID
            resultsTable.Columns.Add(IDColumnName, typeof(string));
            resultsTable.Columns.Add(TitleColumnName, typeof(string));

            List<string> createdFieldNames = new List<string>();
            // And add a column for each item in the default view
            SPList list = LookupPickerDialog.List;
            //foreach (string fieldName in list.DefaultView.ViewFields)
            //{
            //    SPField field = list.Fields.GetField(fieldName);
            //    resultsTable.Columns.Add(field.InternalName, typeof(string));
            //    createdFieldNames.Add(fieldName);
            //}
            foreach (string listViewFieldName in LookupPickerDialog.LookupPicker.PickerData.AllDisplayFields)
            {
                if (createdFieldNames.Contains(listViewFieldName) == false)
                {
                    SPField listViewField = list.Fields.GetField(listViewFieldName);
                    resultsTable.Columns.Add(listViewField.InternalName, typeof(string));
                    createdFieldNames.Add(listViewFieldName);
                }
            }
            //
            // 2. Fill it with data
            //
            #region Build CAML Query
            var contentTypes = LookupPickerDialog.LookupPicker.PickerData.GetContentTypes(list);
           
            var query = new SPQuery().Where(
                QB.And(
                    QB.Contains(groupName, search),
                    QB.Or(
                        contentTypes.Select(ct => QB.IsContentType(ct.Id)).ToArray())));

            if (!string.IsNullOrEmpty(LookupPickerDialog.LookupPicker.PickerData.SearchScope))
            {
                query.ViewAttributes = string.Format("Scope=\"{0}\"", LookupPickerDialog.LookupPicker.PickerData.SearchScope);
            }
            #endregion

            // Query the list and build result items
            if (!string.IsNullOrEmpty(search) || LookupPickerDialog.LookupPicker.PickerData.AllowShowAll)
            {
                foreach (SPListItem listItem in list.GetItems(query))
                {
                    List<string> filledFieldNames = new List<string>();

                    ArrayList resultsRow = new ArrayList();
                    resultsRow.Add(listItem["ID"].ToString());
                    resultsRow.Add(listItem.Title);
                    filledFieldNames.Add(IDColumnName);
                    filledFieldNames.Add(TitleColumnName);
                    //foreach (string fieldName in list.DefaultView.ViewFields)
                    //{
                    //    resultsRow.Add(GetFormattedFieldValue(listItem, list.Fields.GetField(fieldName)));
                    //    filledFieldNames.Add(fieldName);
                    //}
                    foreach (string fieldName in LookupPickerDialog.LookupPicker.PickerData.AllDisplayFields)
                    {
                        if (filledFieldNames.Contains(fieldName) == false)
                        {
                            SPField field = list.Fields.GetField(fieldName);
                            resultsRow.Add(GetFormattedFieldValue(listItem,field));
                            filledFieldNames.Add(fieldName);
                        }
                    }
                    resultsTable.Rows.Add(resultsRow.ToArray());
                }
            }
            // Return results
            LookupPickerDialog.Results = resultsTable;
            if (resultsTable.Rows.Count == 0)
            {
                if (String.IsNullOrEmpty(search) && !LookupPickerDialog.LookupPicker.PickerData.AllowShowAll)
                {
                    PickerDialog.ErrorMessage = Res.ErrorEmptySearchText;
                }
                else
                {
                    PickerDialog.ErrorMessage = Res.ErrorNoMatch;
                }
            }
            return resultsTable.Rows.Count;
        }

        private string GetFormattedFieldValue(SPListItem listItem, SPField field)
        {
            var displayText = Convert.ToString(listItem[field.Id]);
            if (string.IsNullOrEmpty(displayText)) { return string.Empty; }
            if (field.FieldValueType == typeof(SPFieldLookupValue))
            {
                return ((SPFieldLookupValue)listItem[field.Id]).LookupValue;
            }
            else if (field.FieldValueType == typeof(SPFieldLookupValueCollection))
            {
                return string.Join(", ", ((SPFieldLookupValueCollection)listItem[field.Id]).Select(luv => luv.LookupValue).ToArray());
            }
            else if (field.Type == SPFieldType.Calculated)
            {
                return Convert.ToString(listItem[field.Id]).Replace("string;#","");
            }
            return displayText;
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            //Initialization: execute query if AllowShowAll is set to TRUE
            if (!Page.IsPostBack && LookupPickerDialog.LookupPicker.PickerData.AllowShowAll)
            {
                base.ExecuteQuery(string.Empty, string.Empty);
            }
        }
    }
}
